package com.huangfu.learning.javabase.java.reflect;

import java.io.*;
import java.util.Properties;

/**
 * Created with IntelliJ IDEA.
 * Author: huangfu.daohui
 * Date: 2018/7/14
 * Time: 15:10
 * Version: 1.0
 * Description:Spring中的IoC的实现原理就是工厂模式加反射机制。
 **/
public class IOCFactoryReflect {
    public static void main(String[] args) throws IOException {
        //测试不用反射的工厂模式
        Fruit fruit = FruitFactory.getFruitInstence("Apple");
        fruit.eat();
        // 测试使用反射机制 参数的className要是累的全路径
        FruitReflect fruitReflect = FruitFactoryReflect.getFruitReflectInstence("com.huangfu.learning.javabase.java.reflect.AppleReflect");
        fruitReflect.eat();
        //
        Properties pro = Init.getPro();
        FruitProperty f = FactoryProperty.getInstanceProperties(pro.getProperty("apple"));
        if (f != null) {
            f.eat();
        }
    }
}

/*******************************↓↓↓↓↓不用反射的工厂↓↓↓↓↓******************************************/
interface Fruit {
    void eat();
}

class Apple implements Fruit {

    public void eat() {
        System.out.println("不用反射机制:eat Apple");
    }
}

class Orange implements Fruit {
    public void eat() {
        System.out.println("不用反射机制:eat Orange");
    }
}

//构造工厂类，后面添加其他实例(梨子、葡萄等)的时候，只需要修改工厂类
class FruitFactory {
    public static Fruit getFruitInstence(String fruitType) {
        // 使用switch case的时候 直接在case中return，不然还会走其他的case
        switch (fruitType) {
            case "Apple":
                return new Apple();
            case "Orange":
                return new Orange();
            default:
                return null;
        }
    }
}

/*******************************↓↓↓↓↓用反射的工厂↓↓↓↓↓******************************************/
interface FruitReflect {
    void eat();
}

class AppleReflect implements FruitReflect {

    public void eat() {
        System.out.println("使用反射机制:eat Apple Reflect");
    }
}

class OrangeReflect implements FruitReflect {
    public void eat() {
        System.out.println("使用反射机制:eat Orange Reflect");
    }
}

//构造工厂类，后面添加其他实例(梨子、葡萄等)的时候，只需要修改工厂类
class FruitFactoryReflect {
    public static FruitReflect getFruitReflectInstence(String className) {
        FruitReflect fruitReflect = null;
        try {
            fruitReflect = (FruitReflect) Class.forName(className).newInstance();
        } catch (InstantiationException e) {
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }
        return fruitReflect;
    }
}

/*******************************↓↓↓↓↓使用反射+配置文件的工厂↓↓↓↓↓******************************************/

interface FruitProperty {
    void eat();
}

class AppleProperty implements FruitProperty {
    public void eat() {
        System.out.println("AppleProperty");
    }
}

class OrangeProperty implements FruitProperty {
    public void eat() {
        System.out.println("OrangeProperty");
    }
}

//操作属性文件类
class Init {
    public static Properties getPro() throws FileNotFoundException, IOException {
        Properties pro = new Properties();
        File f = new File("fruit.properties");
        if (f.exists()) {
            pro.load(new FileInputStream(f));
        } else {
            pro.setProperty("apple", "com.huangfu.learning.javabase.java.reflect.AppleProperty");
            pro.setProperty("orange", "com.huangfu.learning.javabase.java.reflect.OrangeProperty");
            pro.store(new FileOutputStream(f), "FRUIT CLASS");
        }
        return pro;
    }
}

class FactoryProperty {
    public static FruitProperty getInstanceProperties(String className) {
        FruitProperty f = null;
        try {
            f = (FruitProperty) Class.forName(className).newInstance();
        } catch (Exception e) {
            e.printStackTrace();
        }
        return f;
    }
}

